﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows;
using WNADEP.DataCenter.NetworkDataSet;

namespace WNADEP.TCPService
{
    class ServiceManager
    {
        private IPEndPoint _listenEndPoint;// = null;
        private TcpListener _listener;// = null;
        private volatile bool _shouldStop;
        private int _backlog;

        public volatile List<RemoteData> globalRemoteData;

        public void GenerateFakeData(int n)
        {
            String[] macAddressList = { @"78:A1:06:9B:FA:6C",
                                        @"30:FC:68:43:E1:44",
                                        @"30:49:3B:08:24:D2",
                                        @"42:49:3B:08:24:D2",
                                        @"30:FC:68:16:57:FE",
                                        @"F0:B4:29:69:1F:2D",
                                        @"50:BD:5F:92:41:7E",
                                        @"30:49:3B:08:1C:AC",
                                        @"42:49:3B:08:1C:AC",
                                        @"30:49:3B:08:37:B6",
                                        @"42:49:3B:08:37:B6",
                                        @"6C:E8:73:AF:F3:8A" };
            String[] ssidList = {   @"MERCURY_9BFA6C",
                                    @"511",
                                    @"CMCC-EDU",
                                    @"CMCC-Young",
                                    @"ZZHW",
                                    @"heihei",
                                    @"MERCURY_417E",
                                    @"CMCC-EDU",
                                    @"CMCC-Young",
                                    @"CMCC-EDU",
                                    @"CMCC-Young",
                                    @"RUKUN" };

            String[] protocolTypeList = { "tcp", "udp", "icmp" };
            String[] appProtocolList = {"HTTP", "HTTPS", "TELNET", "SSH", "OTHER"};
            String[] sipList = new String[12];
            bool[] emergentList = {true, false};
            for (int i = 0; i < 12; i++)
               sipList[i] = String.Format("192.168.1.{0}", i.ToString());
            String[] dipList = new String[12];
            for (int i = 12; i < 12+12; i++)
                dipList[i-12] = String.Format("192.168.190.{0}", i.ToString());
            n = n < 12 ? n : 12;
            globalRemoteData = new List<RemoteData>();
            Random rm = new Random();
            for (int i = 0; i < n; i++)
            {
                RemoteData tmpRemoteData = new RemoteData();
                tmpRemoteData.SSID = ssidList[i];
                tmpRemoteData.SIP = sipList[i];
                tmpRemoteData.SPort = rm.Next(1024, 65536).ToString();
                tmpRemoteData.DIP = dipList[i];
                tmpRemoteData.DPort = rm.Next(65536).ToString();
                tmpRemoteData.ProtocolType = protocolTypeList[rm.Next(protocolTypeList.Length - 1)];
                tmpRemoteData.Protocol = appProtocolList[rm.Next(appProtocolList.Length - 1)];
                tmpRemoteData.IsEmergent = emergentList[rm.Next(2)];
                this.globalRemoteData.Add(tmpRemoteData);
            }
        }

        public void RequestStop()
        {
            this._shouldStop = true;
        }
        public void RequestStart()
        {
            this._shouldStop = false;
        }
        //private Thread _listenThread;

        public void InitService(String ipAddress, int port, int backlog=3)
        {
            _listenEndPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
            _listener = new TcpListener(_listenEndPoint);
            _backlog = backlog;
            //_listenThread = new Thread(new ThreadStart(ListenForClient));
        }

        private void ListenForClient()
        {
            
            while ( !_shouldStop )
            {
                TcpClient tcpClient = _listener.AcceptTcpClient();

                Thread tcpClientThread = new Thread(new ParameterizedThreadStart(HandlieClientComm));
                tcpClientThread.Start(tcpClient);

            }
            this.StopService();
        }

        private void HandlieClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;
            ASCIIEncoding encoder = new ASCIIEncoding();
            GenerateFakeData(12);
            while (true)
            {
                bytesRead = 0;

                try
                {
                    //blocks until a client sends a message
                    bytesRead = clientStream.Read(message, 0, 4096);
                    //Console.Write(bytesRead);
                    MessageBox.Show( bytesRead.ToString() + encoder.GetString(message, 0, bytesRead));
                }
                catch
                {
                    //a socket error has occured
                    break;
                }

                if (bytesRead == 0)
                {
                    //the client has disconnected from the server
                    break;
                }

                //message has successfully been received
                
                System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
            }

            tcpClient.Close();
        }



        public void StartService()
        {
            //_listener.Start(backlog);
            _listener.Start(_backlog);

            //while (!_shouldStop)
            //{
            //    GenerateFakeData(12);
            //    Thread.Sleep(3000);
            //}

            //!!!!!!!!!
            ListenForClient();
            
        }

        public void StopService()
        {
            //_listenThread.Join();
            _shouldStop = true;
            _listener.Stop();
            //_listenThread.
        }
    }
}
